#include "datetime.h"
#include "str.h"

Datetime::Datetime(time_t t)
{
	_t = t;
}

Datetime::Datetime(const Datetime &other)
{
	this->_t = other._t;
}

Datetime::~Datetime()
{
}

Datetime &Datetime::operator = (const Datetime &other)
{
	if (this == &other){
		return *this;
	}
	this->_t = other._t;
	return *this;
}

int Datetime::getYear()
{
	struct tm *t;
	t = localtime(&_t);
	return (t->tm_year+1900);
}

int Datetime::getMonth()
{
	struct tm *t;
	t = localtime(&_t);
	return (t->tm_mon+1);
}

int Datetime::getDay()
{
	struct tm *t;
	t = localtime(&_t);
	return t->tm_mday;
}

int Datetime::getHour()
{
	struct tm *t;
	t = localtime(&_t);
	return t->tm_hour;
}

int Datetime::getMinute()
{
	struct tm *t;
	t = localtime(&_t);
	return t->tm_min;
}

int Datetime::getSecond()
{
	struct tm *t;
	t = localtime(&_t);
	return t->tm_sec;
}

int Datetime::getYearDay()
{
	struct tm *t;
	t = localtime(&_t);
	return t->tm_yday;
}

int Datetime::getDaysOfMonth(int year, int month)
{
	switch (month) {
	case 2:
		if ((((year % 4) == 0) && ((year % 100) != 0)) || ((year % 400) == 0))
			return 29;
		else
			return 28;
	case 4:
	case 6:
	case 9:
	case 11: 
  		return 30;
	default: 
		return 31;
  }
}

int Datetime::getDaysOfYear(int year)
{
	return getDaysOfMonth(year,2) + 337;
}

int Datetime::subDate(const char *date1, const char *date2, int &dec)
{
	int day1, day2;
	 
	day1 = date2long(date1);
	day2 = date2long(date2);
	if (day1 == -1 || day2 == -1) return -1;
	dec = day1 - day2;
	return 0;
}

bool Datetime::checkDate(const char *date)
{
	if (Str::isdigit(date) == false) return false;
	if (strlen(date) != 8) return false;
	
	char tmp[8];
	int year, month, day;
	
	strncpy(tmp, date, 4); tmp[4] = 0; year = atoi(tmp);
	strncpy(tmp, date+4, 2); tmp[2] = 0; month = atoi(tmp);
	strncpy(tmp, date+6, 2); tmp[2] = 0; day = atoi(tmp);
	
	if (year<1900) return false;
	if (month<1 || month>12) return false;
	if (day<1 || day>getDaysOfMonth(year, month)) return false;
	
	return true;
}

int Datetime::long2date(int days,char *date)
{
	int year,month;
	
	for (year=1900; days>0; days=days-getDaysOfYear(year++)) ;
	
	year--;
	days = days + getDaysOfYear(year);
	
	for (month=1; days>0; days=days-getDaysOfMonth(year,month++)) ;
	
	month--;
	
	days = days + getDaysOfMonth(year,month);
	
	sprintf(date,"%04d%02d%02d",year,month,days);
	
	return 0;
}

int Datetime::date2long(const char *date)
{
	int len = strlen(date);
	char year[5],month[3],day[3];
	int y,m,d;
	int i;
	int days = 0;
	
	if (len != 8){
		return -1;
	}
	if (strcmp(date,"18991231") == 0){
		return 0;
	}
	
	strncpy(year,date,4);
	year[4] = 0;
	strncpy(month,date+4,2);
	month[2] = 0;
	strncpy(day,date+6,2);
	day[2] = 0;
	
	y = atoi(year);
	m = atoi(month);
	d = atoi(day);
	
	if (y<1900 || y>3000){
		return -1;
	}
	if (m<=0 || m>12){
		return -1;
	}
	if (d<=0 || d>31){
		return -1;
	}
	
	for (i=1900; i<y; i++){
		days += getDaysOfYear(i);
	}
	for (i=1; i<m; i++){
		days += getDaysOfMonth(y,i);
	}
	days += d;
	
	return days;
}

int Datetime::fillDate(const char *date, char *date2)
{
	int len = (int)strlen(date);
	int year, month, day;
	char tmp[8];
	
	if (len < 6) return -1;
	if (Str::isdigit(date) == false) return -1;
	
	strncpy(tmp, date, 4); tmp[4] = 0; year = atoi(tmp);
	strncpy(tmp, date+4, 2); tmp[2] = 0; month = atoi(tmp);
	
	if (year < 1900) return -1;
	if (month<1 || month>12) return -1;
	
	if (len == 6){	//yyyymm
		day = getDaysOfMonth(year, month);
		sprintf(date2, "%04d%02d%02d", year, month, day);
		return 0;
	}else if (len == 7){ //yyyymmT
		tmp[0] = date[6]; tmp[1] = 0;
		int T = atoi(tmp);
		if (T<1 || T>3) return -1;
		day = T*10;
		if (T == 3){
			day = getDaysOfMonth(year, month);
		}
		sprintf(date2, "%04d%02d%02d", year, month, day);
		return 0;
	}else if (len == 8){	//yyyymmdd
		strcpy(date2, date);
		return 0;
	}
	
	return -1;
}
